package controllers

import (
	"dmsv/common"
	"dmsv/etc"
	"dmsv/process"
	"dmsv/reqcache"
	"encoding/json"
	"fmt"
	"github.com/beego/beego/v2/core/logs"
	"strconv"
)

type Callv2Controller struct {
	BaseController
}

func (this *Callv2Controller) URLMapping() {
	this.Mapping("notify", this.CallNotify)
	this.Mapping("satisfactionDo", this.SatisfactionDo)
	this.Mapping("callback", this.CallBack)
	this.Mapping("hangup", this.CallBack)
}

type SatisfactionDo struct {
	AppId  string `json:"appId"`
	CallId string `json:"callId"`
}

// @Title 满意度调查
// @Description 启动满意度调查
// @Description display
// @Param   param   body       process.SatisfactionDo     true   ""
// @Success 200     {object}   controllers.Code
// @router  /satisfactionDo [post]
func (this *Callv2Controller) SatisfactionDo() {

	logs.Debug("receive new SatisfactionDo request:%v", string(this.Ctx.Input.RequestBody))
	param := make(map[string]string)
	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &param); err != nil {
		logs.Error("json error:%v", err)
		this.Data["json"] = ParamsError
		this.ServeJSON()
		return
	}

	appId := param["appId"]
	callId := param["callId"]
	err := process.SatisfactionDo(appId, callId)
	if err != nil {
		this.Data["json"] = QueRegFail
	} else {
		this.Data["json"] = Success
	}

	this.ServeJSON()
	return
}

// @Title 语音通知
// @Description 语音通知
// @Description display
// @Param   param   body       process.Notifyv2Args     true   ""
// @Success 200     {object}   controllers.Code
// @router  /notify [post]
func (this *Callv2Controller) CallNotify() {

	logs.Debug("receive new notify request:%v", string(this.Ctx.Input.RequestBody))
	param := process.Notifyv2Args{GetKey: false}
	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &param); err != nil {
		this.Data["json"] = ParamsError
		this.ServeJSON()
		return
	}

	playFile := etc.Conf.Base.Media + "/" + param.PlayFile
	if false == common.FileIsExist(playFile) {

		this.Data["json"] = FileNotExist
		this.ServeJSON()
		return
	}

	param.PlayFile = playFile
	if param.PlayTime == 0 {
		param.PlayTime = 1
	}

	//检测号码内容，必须为数字
	_, err := strconv.Atoi(param.Number)
	if err != nil {
		logs.Error("被叫号码不正确:%v:%v", param.Number, err)
		this.Data["json"] = NumberError
		this.ServeJSON()
		return
	}

	/*
		if len(param.Number) > 14 || len(param.Number) < 11 {
			this.Data["json"] = NumberError
			this.ServeJSON()
			return
		}
	*/

	if param.CallBack == "" {
		param.CallBack = etc.Conf.Base.CallBack
	}

	callid, err := process.CallNotifyv2(param)
	if err != nil {
		this.Data["json"] = CallIsFullError
		this.ServeJSON()
		return
	}

	this.Data["json"] = SuccCodeCallId(callid)
	this.ServeJSON()
	return

}

type OutCallController struct {
	BaseController
}

func (this *OutCallController) URLMapping() {
	this.Mapping("add", this.AddTask)
	this.Mapping("addTaskNumber", this.AddCallNumber)
}

// @Title 创建预测外呼
// @Description 创建预测外呼任务，先呼叫坐席，待坐席接听后呼叫用户
// @Param   param   body   controllers.GuessCallParam     true   ""
// @Success 200 {object}   controllers.Code
// @Failure 400
// @Failure 404
// @router /add [post]
func (this *OutCallController) AddTask() {

	params := GuessCallParam{}
	logs.Info("add new guess out call: %v", string(this.Ctx.Input.RequestBody))
	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &params); err != nil {
		this.Data["json"] = ParamsError
		this.ServeJSON()
		return
	}

	res := process.CreateGuessCallTask(params.CompanyId, params.TaskId, params.Speed)
	if res {
		this.Data["json"] = Success
	} else {
		this.Data["json"] = QueRegFail
	}

	this.ServeJSON()
	return
}

// @Title 增加预测外呼号码
// @Description 为预测外呼任务增加号码
// @Param   param   body   controllers.TaskNumberParam     true   ""
// @Success 200 {object}   controllers.Code
// @Failure 400
// @Failure 404
// @router /addTaskNumber [post]
func (this *OutCallController) AddCallNumber() {

	params := TaskNumberParam{}
	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &params); err != nil {
		this.Data["json"] = ParamsError
		this.ServeJSON()
		return
	}

	logs.Info("add new guess for compnay:%v,taskId:%v, number: %v  ", params.AppId, params.TaskId, len(params.Numbers))
	res := process.AddGuessCallNumber(params.AppId, params.TaskId, params.Numbers)
	if res {
		this.Data["json"] = Success
	} else {
		this.Data["json"] = QueRegFail
	}

	this.ServeJSON()
	return
}

// @Title 坐席外呼
// @Description 坐席外呼
// @Param   param   body   controllers.SipCallBack     true   "reqId为请求Id,10s内唯一，用以规避重复请求"
// @Success 200 	{object}   controllers.ResultBs
// @router /callback [post]
func (this *Callv2Controller) CallBack() {

	params := SipCallBack{}
	logs.Info("new call back: %v", string(this.Ctx.Input.RequestBody))
	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &params); err != nil {

		logs.Error("json failed:%v", err)
		this.Data["json"] = ParamsError
		this.ServeJSON()
		return
	}

	if !reqcache.IsValid(params.ReqId) {
		errmsg := fmt.Sprintf("reqId %v is request before", params.ReqId)
		this.Data["json"] = &ResultBs{10000, errmsg, ""}
		this.ServeJSON()
		return
	}

	if len(params.Display) > 0 {
		if _, err := strconv.Atoi(params.Display); err != nil {
			errmsg := fmt.Sprintf("dsplay is invalid", params.Display)
			this.Data["json"] = &ResultBs{10001, errmsg, ""}
			this.ServeJSON()
			return
		}
	}

	callId, err := process.CallBackService(params.AppId, params.Service, params.Number, params.Display, params.CallBack)
	if err == nil {
		this.Data["json"] = &ResultBs{0, "success", callId}
	} else {

	}

	this.ServeJSON()
}

// @Title 坐席外呼
// @Description 坐席外呼
// @Param   param   body   controllers.SipCallBack     true   "reqId为请求Id,10s内唯一，用以规避重复请求"
// @Success 200 	{object}   controllers.ResultBs
// @router /hangup [post]
func (this *Callv2Controller) HangUp() {

	params := HangParam{}
	logs.Info("hangup the call: %v", string(this.Ctx.Input.RequestBody))
	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &params); err != nil {
		logs.Error("json failed:%v", err)
		this.Data["json"] = ParamsError
		this.ServeJSON()
		return
	}

	err := process.HangUpTheCall(params.AppId, params.CallId)
	if err != nil {
		this.Data["json"] = AppIdNotExist
		this.ServeJSON()
		return
	}
	this.Data["json"] = Success
	return
}
